package com.ujs.leetcode.reverseString;

import java.util.Arrays;

/**
 * @author zhangshihao
 * @create 2023-10-19 20:20
 * 541. 反转字符串 II
 * https://leetcode.cn/problems/reverse-string-ii/description/
 */
public class ReverseString2 {
    public static void main(String[] args) {
        // String s = "krmyfshbspcgtesxnnljhfursyissjnsocgdhgfxubewllxzqhpasguvlrxtkgatzfybprfmmfithphckksnvjkcvnsqgsgosfxc";
        String s = "abcdefg";
        int k = 8;
        System.out.println(reverseStr2(s, k));
    }

    public static String reverseStr(String s, int k) {
        if (k == 1) {
            return s;
        }
        int n = s.length() / (2 * k); // 可以被反转的字符串
        char[] leave = s.substring(2 * n * k).toCharArray();// 剩下的字符串
        String result = "";
        int distance = 2 * k;
        for (int i = 0; i < n; i++) {
            System.out.println(i * distance + "---" + (i + 1) * distance);
            char[] temp = s.substring(i * distance, (i + 1) * distance).toCharArray();
            // 开始交换
            reverseCharArray(temp, k);
            result += String.valueOf(temp);
        }

        if (leave.length >= k) {
            reverseCharArray(leave, k);
        } else {
            reverseCharArray(leave, leave.length);
        }
        result += String.valueOf(leave);
        return result;
    }

    public static void reverseCharArray(char[] s, int k) {
        int left = 0, right = k - 1;
        while (left < right) {
            s[left] ^= s[right];
            s[right] ^= s[left];
            s[left] ^= s[right];
            left++;
            right--;
        }
    }

    public static String reverseStr2(String s, int k) {
        StringBuffer res = new StringBuffer();
        int length = s.length();
        int start = 0;
        while (start < length) {
            // 找到k处和2k处
            StringBuffer temp = new StringBuffer();
            // 与length进行判断，如果大于length了，那就将其置为length
            int firstK = (start + k > length) ? length : start + k;
            int secondK = (start + 2 * k > length) ? length : start + 2 * k;

            // 无论start所处位置，至少会反转一次
            temp.append(s.substring(start, firstK));
            res.append(temp.reverse());
            // 如果firstK到secondK之间有元素，这些元素直接放入res里即可
            if (firstK < secondK) { // 此时剩余长度一定大于k
                res.append(s.substring(firstK, secondK));
            }
            start += (2 * k);
        }
        return res.toString();
    }


    public static String reverseStr3(String s, int k) {
        char[] ch = s.toCharArray();
        for (int i = 0; i < ch.length; i += 2 * k) {
            int start = i;
            // 这里判断尾数够不够k个来取决end指针的位置
            int end = Math.min(ch.length - 1, start + k - 1);
            // 用异或运算反转
            while (start < end) {
                ch[start] ^= ch[end];
                ch[end] ^= ch[start];
                ch[start] ^= ch[end];
                start++;
                end--;
            }
        }
        return new String(ch);
    }

    public static String reverseStr4(String s, int k) {
        char[] ch = s.toCharArray();
        // 1.每隔 2k 个字符的前 k 个字符进行反转
        for (int i = 0; i < ch.length; i += 2 * k) {
            // 2.剩余字符小于 2k 但大于或等于 k 个，则反转前 k 个字符
            if (i + k < ch.length) {
                reverse(ch, i, i + k - 1);
                continue;
            }
            // 3.剩余字符少于 k 个，则将剩余字符全部翻转
            reverse(ch, i, ch.length - 1);
        }
        return new String(ch);
    }

    public static void reverse(char[] ch, int i, int j) {
        for (; i < j; i++, j--) {
            char temp = ch[i];
            ch[i] = ch[j];
            ch[j] = temp;
        }
    }
}
